package com.ccsoft.annoreflect.service.impl;

import com.ccsoft.annoreflect.anno.TableField;
import com.ccsoft.annoreflect.mapper.BaseMapper;
import com.ccsoft.annoreflect.service.BaseService;
import com.ccsoft.annoreflect.utils.ReflectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author chanchaw
 * @create 2022-09-24 10:24
 */
@Component
public class MBBaseServiceImpl<T> implements BaseService<T> {

    @Autowired
    private BaseMapper mapper;

    @Override
    public List<T> queryList(Object obj) throws InvocationTargetException, IllegalAccessException, SQLException, InstantiationException {
        final ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        Class<T> modelClass = (Class<T>)type.getActualTypeArguments()[0];

        // 将传入的实例对象的各个属性以及value填充到 map ，之后传递给 mybatis.mapper 使用
        Class<?> objClazz = obj.getClass();
        Map<String,Object> params = new HashMap<>();
        for(Field field:objClazz.getDeclaredFields()){
            Object fieldValue = ReflectUtils.getFieldValue(obj, field);
            if(fieldValue == null) params.put(field.getName(),null);
            else params.put(field.getName(),fieldValue);
        }

        List<T> result = new ArrayList<>();
        List<Map<String,Object>> ret = mapper.queryList(params,modelClass);

        for(Map<String,Object> item : ret){
            T newRecord = modelClass.newInstance();

            Field[] fields = modelClass.getDeclaredFields();
            for(Field field:fields){
                String setterMethodName = ReflectUtils.getSetterMethodName(field);
                Method setterMethod =null;
                try {
                    setterMethod = modelClass.getMethod(setterMethodName);
                } catch (NoSuchMethodException e) {
                    continue;
                }

                TableField fieldAnnotation = field.getAnnotation(TableField.class);
                if( fieldAnnotation == null) continue;
                String fieldName = fieldAnnotation.fieldName();
                setterMethod.invoke(newRecord,item.get(fieldName));
            }

            result.add(newRecord);
        }


        return result;
    }

    @Override
    public int delete(Object obj) throws SQLException, InvocationTargetException, IllegalAccessException, NoSuchMethodException {
        final ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        Class<T> modelClass = (Class<T>)type.getActualTypeArguments()[0];

        // 将传入的实例对象的各个属性以及value填充到 map ，之后传递给 mybatis.mapper 使用
        Class<?> objClazz = obj.getClass();
        Map<String,Object> params = new HashMap<>();
        for(Field field:objClazz.getDeclaredFields()){
            Object fieldValue = ReflectUtils.getFieldValue(obj, field);
            if(fieldValue == null) continue;
            params.put(field.getName(),fieldValue);
        }

        return mapper.delete(params,modelClass);
    }



    @Override
    public int update(Object obj) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException, SQLException {
        final ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
        Class<T> modelClass = (Class<T>)type.getActualTypeArguments()[0];

        // 将传入的实例对象的各个属性以及value填充到 map ，之后传递给 mybatis.mapper 使用
        Class<?> objClazz = obj.getClass();
        Map<String,Object> params = new HashMap<>();
        for(Field field:objClazz.getDeclaredFields()){
            Object fieldValue = ReflectUtils.getFieldValue(obj, field);
            if(fieldValue == null) params.put(field.getName(),null);
            else params.put(field.getName(),fieldValue);
        }

        return mapper.update(params,modelClass);
    }
}
